﻿/*
 * scada.cpp
 *
 *  Created on: 2017年3月23日
 *      Author: work
 */

#include <dm/export.hpp>

#define DM_API_SCADA DM_API_EXPORT

#include <dm/scada/types.hpp>
#include <dm/scada/scada.hpp>

#include <dm/env/cfg.hpp>
#include <dm/os/log/logger.hpp>

#include <dm/os/db/db.hpp>
#include <dm/scada/scadaloader.hpp>

#include <boost/interprocess/managed_shared_memory.hpp>

#include <dm/scada/scadainfo.hpp>

#include <dm/scada/deviceinfo.hpp>
#include <dm/scada/statusinfo.hpp>
#include <dm/scada/statusdescinfo.hpp>
#include <dm/scada/discreteinfo.hpp>
#include <dm/scada/discretedescinfo.hpp>
#include <dm/scada/measureinfo.hpp>
#include <dm/scada/cumulantinfo.hpp>
#include <dm/scada/remotectlinfo.hpp>
#include <dm/scada/remotectldescinfo.hpp>
#include <dm/scada/parainfo.hpp>
#include <dm/scada/actioninfo.hpp>
#include <dm/scada/actiondescinfo.hpp>

#include <dm/scada/logicdeviceinfo.hpp>
#include <dm/scada/devicestate.hpp>

namespace dm{
namespace scada{

using namespace boost::interprocess;

static const char* logModule = "CScada.scada.dm";

/**
 * 构造函数
 * 事实上，这个函数在进程中，只会被执行一次。
 */
CScada::CScada(){
	try{
		permissions p;
		p.set_unrestricted();
		static managed_shared_memory memmgr(open_or_create,logModule,1024l*dm::env::CCfg::ins().scada_allocate(),0,p);

		m_info = memmgr.find_or_construct<CScadaInfo>(unique_instance)();

		m_deviceInfos = m_info->deviceCount()<=0?NULL:memmgr.find_or_construct<SDeviceInfo>(unique_instance)[m_info->deviceCount()]();
		m_statusInfos = m_info->statusCount()<=0?NULL:memmgr.find_or_construct<SStatusInfo>(unique_instance)[m_info->statusCount()]();
		m_statusDescInfos = m_info->statusDescCount()<=0?NULL:memmgr.find_or_construct<SStatusDescInfo>(unique_instance)[m_info->statusDescCount()]();
		m_discreteInfos = m_info->discreteCount()<=0?NULL:memmgr.find_or_construct<SDiscreteInfo>(unique_instance)[m_info->discreteCount()]();
		m_discreteDescInfos = m_info->discreteDescCount()<=0?NULL:memmgr.find_or_construct<SDiscreteDescInfo>(unique_instance)[m_info->discreteDescCount()]();
		m_measureInfos = m_info->measureCount()<=0?NULL:memmgr.find_or_construct<SMeasureInfo>(unique_instance)[m_info->measureCount()]();
		m_cumulantInfos = m_info->cumulantCount()<=0?NULL:memmgr.find_or_construct<SCumulantInfo>(unique_instance)[m_info->cumulantCount()]();
		m_remoteCtlInfos = m_info->remoteCtlCount()<=0?NULL:memmgr.find_or_construct<SRemoteCtlInfo>(unique_instance)[m_info->remoteCtlCount()]();
		m_remoteCtlDescInfos = m_info->remoteCtlDescCount()<=0?NULL:memmgr.find_or_construct<SRemoteCtlDescInfo>(unique_instance)[m_info->remoteCtlDescCount()]();
		m_parameterInfos = m_info->parameterCount()<=0?NULL:memmgr.find_or_construct<SParaInfo>(unique_instance)[m_info->parameterCount()]();
		m_actionInfos = m_info->actionCount()<=0?NULL:memmgr.find_or_construct<SActionInfo>(unique_instance)[m_info->actionCount()]();
		m_actionDescInfos = m_info->actionDescCount()<=0?NULL:memmgr.find_or_construct<SActionDescInfo>(unique_instance)[m_info->actionDescCount()]();

		m_logicDeviceInfos = m_info->logicDeviceCount()<=0?NULL:memmgr.find_or_construct<SLogicDeviceInfo>(unique_instance)[m_info->logicDeviceCount()]();

		m_map2logicStatus = m_info->mapedStatusCount()<=0?NULL:memmgr.find_or_construct<index_t>("map2logicstatus")[m_info->mapedStatusCount()](-1);
		m_map2logicDiscrete = m_info->mapedDiscreteCount()<=0?NULL:memmgr.find_or_construct<index_t>("map2logicdiscrete")[m_info->mapedDiscreteCount()](-1);
		m_map2logicMeasure = m_info->mapedMeasureCount()<=0?NULL:memmgr.find_or_construct<index_t>("map2logicmeasure")[m_info->mapedMeasureCount()](-1);
		m_map2logicCumulant = m_info->mapedCumulantCount()<=0?NULL:memmgr.find_or_construct<index_t>("map2logiccumulant")[m_info->mapedCumulantCount()](-1);
		m_map2logicRemoteCtl = m_info->mapedRemoteCtlCount()<=0?NULL:memmgr.find_or_construct<index_t>("map2logicremotectl")[m_info->mapedRemoteCtlCount()](-1);
		m_map2logicParameter = m_info->mapedParameterCount()<=0?NULL:memmgr.find_or_construct<index_t>("map2logicparameter")[m_info->mapedParameterCount()](-1);
		m_map2logicAction = m_info->mapedActionCount()<=0?NULL:memmgr.find_or_construct<index_t>("map2logicaction")[m_info->mapedActionCount()](-1);

		m_map2Status = m_info->logicStatusCount()<=0?NULL:memmgr.find_or_construct<index_t>("mapedstatus")[m_info->logicStatusCount()](-1);
		m_map2Discrete = m_info->logicDiscreteCount()<=0?NULL:memmgr.find_or_construct<index_t>("mapeddiscrete")[m_info->logicDiscreteCount()](-1);
		m_map2Measure = m_info->logicMeasureCount()<=0?NULL:memmgr.find_or_construct<index_t>("mapedmeasure")[m_info->logicMeasureCount()](-1);
		m_map2Cumulant = m_info->logicCumulantCount()<=0?NULL:memmgr.find_or_construct<index_t>("mapedcumulant")[m_info->logicCumulantCount()](-1);
		m_map2RemoteCtl = m_info->logicRemoteCtlCount()<=0?NULL:memmgr.find_or_construct<index_t>("mapedremotectl")[m_info->logicRemoteCtlCount()](-1);
		m_map2Parameter = m_info->logicParameterCount()<=0?NULL:memmgr.find_or_construct<index_t>("mapedparameter")[m_info->logicParameterCount()](-1);
		m_map2Action = m_info->logicActionCount()<=0?NULL:memmgr.find_or_construct<index_t>("mapedaction")[m_info->logicActionCount()](-1);

		m_deviceStates = m_info->deviceCount()<=0?NULL:memmgr.find_or_construct<CDeviceState>(unique_instance)[m_info->deviceCount()]();

		m_statuses = m_info->statusCount()<=0?NULL:memmgr.find_or_construct<status_t>(unique_instance)[m_info->statusCount()]();
		m_discretes = m_info->discreteCount()<=0?NULL:memmgr.find_or_construct<discrete_t>(unique_instance)[m_info->discreteCount()]();
		m_measures = m_info->measureCount()<=0?NULL:memmgr.find_or_construct<measure_t>(unique_instance)[m_info->measureCount()]();
		m_cumulants = m_info->cumulantCount()<=0?NULL:memmgr.find_or_construct<cumulant_t>(unique_instance)[m_info->cumulantCount()]();

		m_eventQueue = memmgr.find_or_construct<event_queue_t>(unique_instance)();
		m_measureQueue = memmgr.find_or_construct<measure_queue_t>(unique_instance)();
		m_cumulantQueue = memmgr.find_or_construct<cumulant_queue_t>(unique_instance)();

		// 初始化数据
		memmgr.find_or_construct<CScadaLoader>(unique_instance)(this);
	}catch( interprocess_exception& e ){
		log().error(STATICMODULE "内存分配失败%s",e.what());
	}catch( ... ){
		log().error(STATICMODULE "未知异常");
	}
}

/**
 * 拷贝构造函数。主要用于构造基于ins()对象。
 * @param scada 这个对象一般由ins()函数来获取。
 */
CScada::CScada( CScada& scada ):m_info(scada.m_info),
		m_deviceInfos(scada.m_deviceInfos),
		m_statusInfos(scada.m_statusInfos),m_statusDescInfos(scada.m_statusDescInfos),
		m_discreteInfos(scada.m_discreteInfos),m_discreteDescInfos(scada.m_discreteDescInfos),
		m_measureInfos(scada.m_measureInfos),m_cumulantInfos(scada.m_cumulantInfos),
		m_remoteCtlInfos(scada.m_remoteCtlInfos),m_remoteCtlDescInfos(scada.m_remoteCtlDescInfos),
		m_parameterInfos(scada.m_parameterInfos),
		m_actionInfos(scada.m_actionInfos),m_actionDescInfos(scada.m_actionDescInfos),
		m_logicDeviceInfos(scada.m_logicDeviceInfos),
		m_map2logicStatus(scada.m_map2logicStatus),m_map2logicDiscrete(scada.m_map2logicDiscrete),
		m_map2logicMeasure(scada.m_map2logicMeasure),m_map2logicCumulant(scada.m_map2logicCumulant),
		m_map2logicRemoteCtl(scada.m_map2logicRemoteCtl),m_map2logicParameter(scada.m_map2logicParameter),
		m_map2logicAction(scada.m_map2logicAction),
		m_map2Status(scada.m_map2Status),m_map2Discrete(scada.m_map2Discrete),
		m_map2Measure(scada.m_map2Measure),m_map2Cumulant(scada.m_map2Cumulant),
		m_map2RemoteCtl(scada.m_map2RemoteCtl),m_map2Parameter(scada.m_map2Parameter),
		m_map2Action(scada.m_map2Action),
		m_deviceStates(scada.m_deviceStates),
		m_statuses(scada.m_statuses),m_discretes(scada.m_discretes),
		m_measures(scada.m_measures),m_cumulants(scada.m_cumulants),
		m_eventQueue(scada.m_eventQueue),m_measureQueue(scada.m_measureQueue),
		m_cumulantQueue(scada.m_cumulantQueue){
}

/**
 * 获取全局唯一对象
 * @return
 */
CScada& CScada::ins(){
	static CScada i;
	return i;
}

/**
 * 复位scada系统。
 */
void CScada::reset(){
	try{
		shared_memory_object::remove(logModule);
	}catch( interprocess_exception& e ){
		log().error(STATICMODULE "内存删除失败%s",e.what());
	}
}

}
}


